package com.tc.vms.config;

import com.tc.vms.iface.IContext;
import com.tc.vms.utils.Utils;
import com.tc.vms.utils.VmsDomainAttr;
import com.tc.vms.utils.ZkBootOptions;
import com.tc.vms.utils.ZkUtils;

/**
 * <code>VmsClientContext</code> vmsclient运行时的环境变量
 * <p>Here are some more examples of how <em>VmsClientContext</em> can be used:
 * <p><blockquote><pre>
 *     VmsClientContext vmsClientContext = new VmsClientContextBuilder().build();
 *     或
 *     VmsClientContextBuilder vmsClientContextBuilder = new VmsClientContext.VmsClientContextBuilder()；
 *     vmsClientContextBuilder.bootstrapPath("boot");
 *     vmsClientContext = vmsClientContextBuilder.build();
 * </pre></blockquote>
 *
 * @author yonghua.zhang.
 * @since vmsclient v1.0.0
 */
public class VmsClientContext implements IContext {
    // vmsclient read bootstrapPath path in the cfg zk to locate vms metadata zk
    private final String bootstrapPath;

    private final String bootstrapChroot;

    //read bootstrapPath data and use field of middlewareName to get metadata zk connection
    private final String middlewareName;

    //metadata zk path
    private final String vmsChroot;

    private String bootstrapCfgCenter = ZkUtils.bootstrapCfgCenter;

    private final VmsDomainAttr belongAttr;

    private final String hostIp = Utils.getHostIp();

    private final ZkBootOptions zkBootOptions;

    {
        String bootAddress = System.getProperty(ZkUtils.bootstrapCfgCenterEnv, System.getenv(ZkUtils.bootstrapCfgCenterEnv));
        if (bootAddress != null && bootAddress.trim().length() > 0) {
            bootstrapCfgCenter = bootAddress;
        }
    }

    public ZkBootOptions getZkBootOptions() {
        return zkBootOptions;
    }

    /**
     * <code>VmsClientContextBuilder</code> 构建vmsclient所需的所有环境变量
     * <blockquote>
     * <code>belongDomain</code>  业务所属域   根据实际业务填写 必填项
     * <p><code>belongAppname</code> 业务服务名称 根据实际业务填写 必填项
     * <p>
     * <p><code>bootstrapChroot</code> 配置中心<em>partition</em>的路径名称
     * <p><code>bootstrapPath</code> 配置中心<em>bootstrap</em>节点路径
     * <p><code>vmsChroot</code> 　　VMS元数据管理ZK <em>partition</em>路径名称
     * <p><code>middlewareName</code> VMS元数据管理ZK 存储<em>channel/queue</em>节点的相对路径
     * <p><code>zkConnectionTimeout</code> 连接<em>zookeeper</em>的超时时间
     * <p><code>zkSessionTimeout</code> 　　连接<em>zookeeper</em>会话超时时间
     * <p><code>build()</code>　返回{@link VmsClientContext}vmsclient环境对象
     */
    public final static class VmsClientContextBuilder {
        private String bootstrapPath = "bootstrap";
        private String bootstrapChroot = "/default";
        private String vmsChroot = bootstrapChroot;
        private String middlewareName = "vms";
        private String belongDomain = "default";
        private String belongAppname = "default";
        private int zkConnectionTimeout = 120 * 1000;
        private int zkSessionTimeout = zkConnectionTimeout;

        public VmsClientContextBuilder() {

            String bootPartition = System.getProperty(ZkUtils.bootstrapCfgPartition, System.getenv(ZkUtils.bootstrapCfgPartition));
            if (bootPartition != null && !bootPartition.trim().isEmpty()) {
                bootstrapChroot = bootPartition.trim();
                bootstrapChroot = bootstrapChroot.charAt(0) != '/' ? ("/" + bootstrapChroot) : bootstrapChroot;
                vmsChroot = bootstrapChroot;
            }

            String vmsPartition = System.getProperty(ZkUtils.vmsPartition, System.getenv(ZkUtils.vmsPartition));
            if (vmsPartition != null && !vmsPartition.trim().isEmpty()) {
                vmsChroot = vmsPartition.trim();
                vmsChroot = vmsChroot.charAt(0) != '/' ? ("/" + vmsChroot) : vmsChroot;
            }

        }

        public VmsClientContextBuilder zkConnectionTimeout(int connectionTimeout) {
            this.zkConnectionTimeout = connectionTimeout;
            return this;
        }

        public VmsClientContextBuilder zkSessionTimeout(int sessionTimeout) {
            this.zkSessionTimeout = sessionTimeout;
            return this;
        }

        public VmsClientContextBuilder bootstrapPath(String bootstrapPath) {
            this.bootstrapPath = bootstrapPath;
            return this;
        }

        public VmsClientContextBuilder bootstrapChroot(String bootstrapChroot) {
            this.bootstrapChroot = bootstrapChroot;
            this.vmsChroot = this.bootstrapChroot;
            return this;
        }

        public VmsClientContextBuilder middlewareName(String middlewareName) {
            this.middlewareName = middlewareName;
            return this;
        }

        public VmsClientContextBuilder vmsChroot(String vmsChroot) {
            this.vmsChroot = vmsChroot;
            return this;
        }

        public VmsClientContextBuilder domain(String belongDomain) {
            this.belongDomain = belongDomain;
            return this;
        }

        public VmsClientContextBuilder appname(String belongAppname) {
            this.belongAppname = belongAppname;
            return this;
        }

        public VmsClientContext build() {
            return new VmsClientContext(bootstrapChroot, bootstrapPath,
                    vmsChroot, middlewareName, new VmsDomainAttr(belongDomain, belongAppname), new ZkBootOptions(zkConnectionTimeout, zkSessionTimeout));
        }
    }

    VmsClientContext(String bootstrapChroot, String bootstrapPath, String vmsChroot, String middlewareName, VmsDomainAttr belongAttr, ZkBootOptions zkBootOptions) {
        this.bootstrapChroot = bootstrapChroot;
        this.bootstrapPath = bootstrapPath;
        this.middlewareName = middlewareName;
        this.vmsChroot = vmsChroot;
        this.belongAttr = belongAttr;
        this.zkBootOptions = zkBootOptions;
    }

    /**
     * 获取Vmsclient Domain相关属性
     *
     * @return {@link VmsDomainAttr}
     */
    public VmsDomainAttr getBelongAttr() {
        return belongAttr;
    }

    /**
     * 获取当前机器的ip地址
     *
     * @return A <tt>String</tt> 机器<em>ip</em>地址
     */
    public String getHostIp() {
        return hostIp;
    }

    public String getBootstrapPath() {
        return bootstrapPath;
    }

    public String getBootstrapChroot() {
        return bootstrapChroot;
    }

    public String getMiddlewareName() {
        return middlewareName;
    }

    public String getVmsChroot() {
        return vmsChroot;
    }

    public String getBootstrapCfgCenter() {
        return bootstrapCfgCenter;
    }

    /**
     * 获取配置中心Bootstrap地址的完整路径
     *
     * @return <tt>String</tt>　bootstrap 完整路径
     */
    public String getBootstrapNodePath() {
        return Utils.mkZkPathString(bootstrapChroot, bootstrapPath);
    }

    /**
     * 获取配置中心<tt>bootstrap</tt>节点内容中指定的vms_zk的连接字符串信息的<em>key</em>标签
     *
     * @return <tt>String</tt>　vms_zk 对应的<em>key</em>标签
     */
    public String getBootstrapNodeTag() {
        return Utils.mkZkPathString("/" + middlewareName, "**");
    }

    /**
     * 获取在vms zookeeper中<tt>channel</tt>的父目录路径
     *
     * @return <tt>String</tt>　channel的父目录路径
     */
    public String getVmsZkChannelParentPath() {
        return Utils.mkZkPathString(vmsChroot, middlewareName, ZkUtils.zkChannelPath);
    }

    /**
     * 获取在vms zookeeper中<tt>queue</tt>的父目录路径
     *
     * @return <tt>String</tt>　queue的父目录路径
     */
    public String getVmsZkQueueParentPath() {
        return Utils.mkZkPathString(vmsChroot, middlewareName, ZkUtils.zkQueuePath);
    }

    /**
     * 获取在vms zookeeper中<tt>Illegal</tt>的父目录路径
     *
     * @return <tt>String</tt>　Illegal的父目录路径
     */
    public String getVmsZkIllegalParentPath() {
        return Utils.mkZkPathString(vmsChroot, middlewareName, ZkUtils.zkIllegalPath);
    }

    /**
     * 获取在vms zookeeper中<tt>Cluster</tt>的父目录路径
     *
     * @return <tt>String</tt>　Cluster的父目录路径
     */
    public String getVmsZkClusterParentPath() {
        return Utils.mkZkPathString(vmsChroot, middlewareName, ZkUtils.zkClusterPath);
    }

    /**
     * 获取在vms zookeeper中<tt>Producer</tt>的父目录路径
     *
     * @return <tt>String</tt>　Producer的父目录路径
     */
    public String getVmsZkProducerParentPath() {
        return Utils.mkZkPathString(vmsChroot, middlewareName, ZkUtils.zkProducerPath);
    }

    /**
     * 获取在vms zookeeper中<tt>channel</tt>的节点完整路径
     *
     * @param cName 指定channel名称
     * @return <tt>String</tt>　channel节点完整路径
     */
    public String getVmsZkChannelNodePath(String cName) {
        return Utils.mkZkPathString(vmsChroot, middlewareName, ZkUtils.zkChannelPath, cName);
    }

    /**
     * 获取在vms zookeeper中<tt>queue</tt>的节点完整路径
     *
     * @param qName 指定queue名称
     * @return <tt>String</tt>　queue节点完整路径
     */
    public String getVmsZkQueueNodePath(String qName) {
        return Utils.mkZkPathString(vmsChroot, middlewareName, ZkUtils.zkQueuePath, qName);
    }

    /**
     * 获取在vms zookeeper中<tt>cluster</tt>的节点完整路径
     *
     * @param clusterName 指定cluster名称
     * @return <tt>String</tt>　cluster节点完整路径
     */
    public String getVmsZkClusterNodePath(String clusterName) {
        return Utils.mkZkPathString(vmsChroot, middlewareName, ZkUtils.zkClusterPath, clusterName);
    }
}
